#!/usr/local/bin/python3
# -*- coding: utf-8 -*-

"""
@File    : func.py
@Author  : Link
@Time    : 2022/5/1 23:41
@Mark    : 
"""
import datetime
import json
import os
import pickle
import random
import time
from typing import Union

import numpy as np
import pandas as pd
from Crypto.Cipher import AES
from binascii import a2b_hex


def qt_catch_except(func):
    """

    :param func:
    :return:
    """

    def wrapper(ctx, *args, **kwargs):
        try:
            ctx.statusbar.clearMessage()
            return func(ctx, *args, **kwargs)
        except Exception as error:
            ctx.message_show('errorfunc: %s' % func.__name__ + f' 报错信息: {error}')
            ctx.enabled_push_button(True)

    return wrapper


def catch_except(func):
    def wrapper(ctx, *args, **kwargs):
        try:
            return func(ctx, *args, **kwargs)
        except Exception as error:
            ctx.message_show('errorfunc: %s' % func.__name__ + f' 报错信息: {error}')

    return wrapper


def tid_maker():
    """
    生成唯一ID
    :return:
    """
    keyStr = '{0:%Y%m%d%H%M%S%f}'.format(datetime.datetime.now()) + ''.join(
        [str(random.randint(0, 9)) for i in range(5)])
    return keyStr[:20]


# 正态分布的概率密度函数。可以理解成 x 是 mu（均值）和 sigma（标准差）的函数
def norm_fun(x, mu, sigma):
    pdf = np.exp(-((x - mu) ** 2) / (2 * sigma ** 2)) / (sigma * np.sqrt(2 * np.pi))
    return pdf


def datetime_to_mktime(date_time: datetime) -> int:
    return int(time.mktime(date_time.timetuple()))


def datetime_str_to_mktime(date_time: str) -> int:
    time_array = time.strptime(date_time, "%Y-%m-%d %H:%M:%S")
    return int(time.mktime(time_array))


def timestamp_to_str(timestamp: int) -> str:
    if timestamp is None:
        return "NULL"
    date_array = datetime.datetime.utcfromtimestamp(timestamp)
    return date_array.strftime("%Y-%m-%d %H:%M:%S")


def json_dump_to_file(data, file_name, suffix='.json', json_encoder=None):
    """
    用于将数据 保存在json文件中, 用于调试
    :param suffix:
    :param file_name:保存的文件名
    :param data:保存的数据帧
    :param json_encoder:
    :return:
    """
    file_path = os.path.join('cache_test_data', file_name + suffix)
    with open(file_path, 'w') as file_obj:
        if json_encoder:
            json.dump(data, file_obj, cls=json_encoder)
        else:
            json.dump(data, file_obj)


def save_df_to_json(data: pd.DataFrame, save_path: str, file_name: str, suffix='.json'):
    file_path = os.path.join('cache_test_data', save_path)
    if not os.path.exists(file_path):
        os.makedirs(file_path)
    full_path = os.path.join(file_path, file_name + suffix)
    data.to_json(full_path)


def get_df_by_json(save_path: str, file_name: str, suffix='.json') -> Union[pd.DataFrame, None]:
    file_path = os.path.join('cache_test_data', f'{save_path}/{file_name}{suffix}')
    if not os.path.exists(file_path):
        return None
    return pd.read_json(file_path)


def save_obj_to_pickle(data, save_path: str, file_name: str, suffix='.pkl'):
    file_path = os.path.join('cache_test_data', save_path)
    if not os.path.exists(file_path):
        os.makedirs(file_path)
    full_path = os.path.join(file_path, file_name + suffix)
    with open(full_path, 'wb') as file_obj:
        data_pik = pickle.dumps(data)
        file_obj.write(data_pik)


def get_obj_by_pickle(save_path: str, file_name: str, suffix='.pkl') -> Union[object, None]:
    file_path = os.path.join('cache_test_data', f'{save_path}/{file_name}{suffix}')
    if not os.path.exists(file_path):
        return None
    with open(file_path, 'rb') as file:
        li = pickle.loads(file.read())
    return li


def generator_pandas_column(string: str, temp: dict) -> str:
    temp_str = string
    c = 0
    while temp_str in temp:
        c += 1
        temp_str = "{}.{}".format(string, c)
    return temp_str


# 获取当前时间戳
def get_now_timestamp():
    return int(int(datetime.datetime.now().timestamp()))


# 解密后，去掉补足的空格用strip() 去掉
def decrypt(key="lagfaw2021bylink", license_str=""):
    iv = b'bylinkghijklmnop'
    mode = AES.MODE_CBC
    cryptos = AES.new(key.encode('utf-8'), mode, iv)
    plain_text = cryptos.decrypt(a2b_hex(license_str.encode('utf-8')))
    return bytes.decode(plain_text).rstrip('\0')


def read_hi() -> bool:
    """
    读取license
    """
    try:
        file_path = "stdf_ana_license.lic"
        with open(file_path, encoding='utf-8') as f:
            aes_license_str = f.read(512)
        return print_hi(aes_license_str)
    except:
        return False


def print_hi(aes_license_str) -> bool:
    """
    先解析, 并和当前时间进行对比
    """
    try:
        st = int(decrypt(license_str=aes_license_str))
    except:
        return False

    if get_now_timestamp() > st:
        return False

    file_path = "stdf_ana_license.lic"
    with open(file_path, 'w', encoding='utf-8') as lic:
        lic.write(aes_license_str)
        lic.close()
    return True
